import os
import time
import tkinter
import tkinter.filedialog
import threading
import pygame


class MusicPlay():
    def __init__(self):
        # 定义一些变量
        self.folder = ''  # 歌曲文件夹路径
        self.res = []  # 存放歌曲路径
        self.ret = []  # 存放歌曲名称
        self.num = 0 # 用于上下首切换定位
        self.one_start = True
        self.playing = False  # 播放限制 为False暂停
        # 界面
        self.root = tkinter.Tk()# 创建窗口对象
        self.root.title('音乐播放器')
        self.root.geometry('460x600+500+100') # 窗口大小
        self.root['bg'] = '#bdbdb8' # 窗口北京
        self.root.resizable(False, False) #固定窗口

    def buttonChooseFile(self):
        """
        添加文件流程
        """
        ''' 获取文件夹路径 '''
        self.folder = tkinter.filedialog.askdirectory() #获取目录
        if self.folder:
            for file in os.listdir(self.folder):# 获取文件夹下所有得文件
                file_abspath = os.path.abspath(os.path.join(self.folder, file))# 拼接绝对路径
                if file.endswith('.mp3'): # 判断后缀
                    self.ret.append(file)  # 保存歌曲名称
                    self.res.append(file_abspath)  # 保存歌曲绝对路径
                else:
                    print('此文件不是mp3：', file)
            if self.ret and self.res: # 绝对路径音乐文件列表，音乐名称列表
                var2 = tkinter.StringVar()
                var2.set(self.ret)

                self.lb = tkinter.Listbox( # self.lb  # 全局变量
                    self.root,
                    listvariable=var2,
                    font=("黑体", 14),
                    bg="#bdbdb8",
                    fg="#1d0102"
                )
                self.lb.place(x=20, y=40, width=310, height=400)
                self.lb.bind("<Double-Button-1>", self.playActive)  # 绑定单击事件
        if not self.folder: #没有获取到地址返回
            return
        # 根据情况禁用和启用相应的按钮
        self.button_play['state'] = 'normal' #播放状态，是否可点击
        self.button_delete['state'] = 'normal' # 删除是否可点击状态

    def set_music_name_flag(self, flag, music_name=None):
        """
        更改提示状态
        """
        if flag:
            self.musicName.set('正在播放歌曲：' + music_name) # 动态更改标签内容
        else:
            self.musicName.set('暂时无播放内容...')

    def set_pause_resume_flag(self, flag):
        """
        更改播放状态
        """
        if flag:
            self.pause_resume.set('播放') # 动态更改标签内容
        else:
            self.pause_resume.set('暂停')

    def playActive(self, *args):
        """
        点击事件流程
        """
        self.close_play()# 关闭播放内容
        self.playing = True  # 播放状态
        self.set_pause_resume_flag(False)  # 播放按钮状态更改
        # 创建线程播放音乐
        t = threading.Thread(target=self.music_play)
        t.start()

    def close_play(self):
        """
        关闭停止当前音乐
        """
        self.playing = False
        pygame.mixer.init()
        pygame.mixer.music.stop()
        self.set_music_name_flag(False)

    def music_play(self):
        """
        播放音乐
        """
        if self.res:
            pygame.mixer.init()# 初始化
            while self.playing: # 单曲循环
                if not pygame.mixer.music.get_busy():
                    music_name = self.lb.get('active')  # 获取歌曲名
                    self.set_music_name_flag(True, music_name)  # 获取歌曲名称状态
                    self.num = self.ret.index(music_name)  # 找寻定位下标
                    nextMusic = self.res[self.num]  # 指定绝对路径歌曲
                    pygame.mixer.music.load(nextMusic.encode())
                    pygame.mixer.music.play(1)# 播放一次

    def buttonDeleteClick(self):
        """
        删除音乐流程
        """
        music = self.lb.get('active') # 获取按钮内容
        num = self.ret.index(music)# 定位索引
        self.ret.remove(music)# 通过元素删除
        del self.res[num]# 通过索引删除
        self.lb.delete('active')# 显示列表删除

    def buttonPlayClick(self):
        """
        播放流程
        """
        self.button_next['state'] = 'normal' # 按钮显示状态
        self.button_prev['state'] = 'normal'
        # 选择要播放的音乐文件
        if self.pause_resume.get() == '播放':
            self.set_pause_resume_flag(False)  # 播放按钮状态更改
            self.playing = True
            # 创建一个线程来播放音乐，当前主线程用来接收用户操作
            t = threading.Thread(target=self.music_play)
            t.start()
        elif self.pause_resume.get() == '暂停':
            self.set_pause_resume_flag(True)  # 播放按钮状态更改
            self.close_play()

    def buttonPrevClick(self):
        """
        上一首
        """
        self.close_play()
        len_num = len(self.res)  # 歌曲总数
        if self.num == 0:
            self.num = len_num - 1
        else:
            self.num -= 1
        self.set_pause_resume_flag(False)  # 播放按钮状态更改
        self.lb.activate(self.num)
        self.lb.see(self.num)
        self.playing = True
        # 创建线程播放音乐
        t = threading.Thread(target=self.music_play)
        t.start()

    def buttonNextClick(self):
        """
        下一首
        """
        self.close_play()
        len_num = len(self.res)  # 歌曲总数
        if self.num == len_num - 1:
            self.num = 0
        else:
            self.num += 1
        self.set_pause_resume_flag(False)  # 播放按钮状态更改
        self.lb.activate(self.num)
        self.lb.see(self.num)
        self.playing = True
        # 创建线程播放音乐
        t = threading.Thread(target=self.music_play)
        t.start()

    def close_button(self):
        """
        退出程序
        """
        self.root.quit()

    def layout_home(self):
        """
        布局主页
        """
        ''' 播放器状态 '''
        play_state = tkinter.StringVar(self.root, value='请先导入音频文件...')
        stateLabel = tkinter.Label(
            self.root,
            textvariable=play_state,
            bg='#bdbdb8',
            fg='#ac1124',
            font=("黑体", 12)
        )
        stateLabel.place(x=50, y=50)


        ''' 添加文件按钮 '''
        button_choose = tkinter.Button(
            self.root,
            text='导入音乐',
            width=10,
            height=2,
            font=("黑体", 12),
            bg="#F0F8FF",
            fg="blue",
            command=self.buttonChooseFile
        )
        button_choose.place(x=350, y=40)


        ''' 删除歌曲按钮 '''
        self.button_delete = tkinter.Button(
            self.root,
            text='删除音乐',
            width=10,
            height=2,
            font=("黑体", 12),
            bg="#F0F8FF",
            fg="#660c15",
            command=self.buttonDeleteClick
        )
        self.button_delete.place(x=350, y=100)
        self.button_delete['state'] = 'disabled'


        ''' 可变字符串组件 '''
        self.pause_resume = tkinter.StringVar(self.root, value='播放')
        ''' 播放按钮 '''
        self.button_play = tkinter.Button(
            self.root,
            textvariable=self.pause_resume,
            width=10,
            height=2,
            font=("黑体", 12),
            bg="#F0F8FF",
            fg="#72c00b",
            command=self.buttonPlayClick
        )
        self.button_play.place(x=350, y=160)
        self.button_play['state'] = 'disabled'


        ''' 上一首 '''
        self.button_prev = tkinter.Button(
            self.root,
            text='上一首',
            width=10,
            height=2,
            font=("黑体", 12),
            bg="#F0F8FF",
            fg="#467213",
            command=self.buttonPrevClick
        )
        self.button_prev.place(x=350, y=220)
        self.button_prev['state'] = 'disabled'


        ''' 下一首 '''
        self.button_next = tkinter.Button(
            self.root,
            text='下一首',
            width=10,
            height=2,
            font=("黑体", 12),
            bg="#F0F8FF",
            fg="#467213",
            command=self.buttonNextClick
        )
        self.button_next.place(x=350, y=280)
        self.button_next['state'] = 'disabled'


        ''' 当前播放的音乐 '''
        self.musicName = tkinter.StringVar(
            self.root,
            value='暂时无播放内容...'
        )
        labelName = tkinter.Label(
            self.root,
            textvariable=self.musicName,
            font=("微软雅黑", 12),
            fg='#008c8c',
            bg='#bdbdb8'
        )
        labelName.place(x=10, y=500)


        ''' 退出程序 '''
        close_button = tkinter.Button(
            self.root,
            text='退出程序',
            width=10,
            height=2,
            font=("黑体", 12),
            bg="#F0F8FF",
            fg="#660c15",
            command=self.close_button
        )
        close_button.place(x=350, y=350)


    def run(self):
        self.layout_home()
        self.root.mainloop()


if __name__ == '__main__':
    # 不可被调用
    mp = MusicPlay()
    mp.run()
